﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using MarioArena.World;
using Microsoft.Xna.Framework;
using MarioArena.Characters;

namespace MarioArena.HUD
{
    public class ScoreBoard
    {
        private const int updateTime = 1000; //update scoreboard every second.
        private const float transparency = 0.4f; //0 = solid, 1 = transparent
        private const int marginTop = 60;
        private const int marginBottom = 80;
        private const int lineSpacing = 35; //space between each line
        private const int width = 500;
        private int height; //height depends on the screen size
        private Color backgroundColor = Color.Black;
        private Color lineColor = Color.White;

        public bool Enabled = true;
        private bool toggled = false;
        private Texture2D backgroundTexture;
        private SpriteFont font; 
        private int screenWidth;
        private int screenHeight;

        private int columnScoreX = 220;
        private int columnDeathsX = 300;
        private int columnPingX = 380;

        private Rectangle outerBounds;
        private Rectangle headerBounds;

        private int innerMargin = 15;
        private int textMargin = 5;
        private Rectangle innerBounds;

        private int elapsedTime = 0;
        private List<Opponent> opponents = new List<Opponent>();

        public void LoadContent()
        {
            backgroundTexture = new Texture2D(GameManager.GraphicsDevice, 1, 1);
            backgroundTexture.SetData(new[] { Color.White });
            font = GameManager.Content.Load<SpriteFont>("Fonts/Scoreboard");

            screenWidth = GameManager.GraphicsDevice.Viewport.Width;
            screenHeight = GameManager.GraphicsDevice.Viewport.Height;

            height = screenHeight - marginTop - marginBottom;
            int x = (screenWidth - width) / 2; //left border of scoreboard.
            int y = marginTop;

            int headerHeight = 100;
            
            outerBounds = new Rectangle(x, y, width, height); //Bounds of entire scoreboard
            headerBounds = new Rectangle(x, y, width, headerHeight); //bounds of scoreboard header
            innerBounds = new Rectangle(x + innerMargin, y + innerMargin + headerHeight, width - (innerMargin * 2), height - (innerMargin * 2) - headerHeight); //bounds of scoreboard beneath header
        }

        /// <summary>
        /// Updates the current data.
        /// </summary>
        private void updateData()
        {
            opponents.Clear();
            List<Opponent> enemies = GameManager.Instance.Opponents;
            foreach (Opponent enemy in enemies) //add all opponents
                opponents.Add(enemy);
        }

        public void Update(GameTime gameTime)
        {
            elapsedTime += gameTime.ElapsedGameTime.Milliseconds;
            if (elapsedTime >= updateTime)
            {
                updateData();
                elapsedTime = 0;
            }
            
            toggled = Keyboard.GetState().IsKeyDown(Keys.Tab);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            //If the ScoreBoard is enabled and toggled by user
            if (Enabled && toggled)
            {
                //draw code
                DrawBackground(spriteBatch);
                DrawHeaders(spriteBatch);
                DrawNamesColumn(spriteBatch);
                DrawScoresColumn(spriteBatch);
                DrawDeathsColumn(spriteBatch);
                DrawPingsColumn(spriteBatch);
            }
        }

        /// <summary>
        /// Draws the background
        /// </summary>
        /// <param name="spriteBatch"></param>
        private void DrawBackground(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(backgroundTexture, outerBounds, backgroundColor * (1 - transparency));
            spriteBatch.Draw(backgroundTexture, new Rectangle(outerBounds.X, outerBounds.Y, 1, outerBounds.Height), Color.DarkGray); //border left
            spriteBatch.Draw(backgroundTexture, new Rectangle(outerBounds.X, outerBounds.Y, outerBounds.Width, 1), Color.DarkGray); //border top
            spriteBatch.Draw(backgroundTexture, new Rectangle(outerBounds.X + outerBounds.Width - 2, outerBounds.Y, 2, outerBounds.Height), Color.Black); //border right
            spriteBatch.Draw(backgroundTexture, new Rectangle(outerBounds.X, outerBounds.Y + outerBounds.Height -2, outerBounds.Width, 2), Color.Black); //border bottom
        }
        /// <summary>
        /// Draws all headers
        /// </summary>
        /// <param name="spriteBatch"></param>
        private void DrawHeaders(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(backgroundTexture, new Rectangle(innerBounds.X, headerBounds.Bottom, outerBounds.Width - (innerMargin *2), 1), Color.DarkGray); //draw line beneath header
            spriteBatch.DrawString(font, "Player", new Vector2(innerBounds.X + textMargin + 15, headerBounds.Y + 60), Color.DarkGray); //draw name header
            spriteBatch.DrawString(font, "Score", new Vector2(innerBounds.X + columnScoreX + textMargin + 15, headerBounds.Y + 60), Color.DarkGray); //draw score header
            spriteBatch.DrawString(font, "Deaths", new Vector2(innerBounds.X + columnDeathsX + textMargin + 15, headerBounds.Y + 60), Color.DarkGray); //draw deaths header
            spriteBatch.DrawString(font, "Latency", new Vector2(innerBounds.X + columnPingX + textMargin + 15, headerBounds.Y + 60), Color.DarkGray); //draw latecy header
        }
        /// <summary>
        /// Draws the name column, which shows all names per player.
        /// </summary>
        /// <param name="spriteBatch"></param>
        private void DrawNamesColumn(SpriteBatch spriteBatch)
        {
            for (int i = 0; i <= opponents.Count; i++)
            {
                Color color = Color.White;
                string name = "You";
                if(i > 0) 
                    name = opponents[i - 1].Name;
                else color = Color.Yellow;
                spriteBatch.DrawString(font, name, new Vector2(innerBounds.X + textMargin, innerBounds.Y + (i * lineSpacing)), color);
            }
        }
        /// <summary>
        /// Draws the scores column, which shows all scores per player.
        /// </summary>
        /// <param name="spriteBatch"></param>
        private void DrawScoresColumn(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(backgroundTexture, new Rectangle(innerBounds.X + columnScoreX, innerBounds.Y, 1, innerBounds.Height), lineColor * (1 - transparency));
            for (int i = 0; i <= opponents.Count; i++)
            {
                Color color = Color.White;
                string score = Player.Instance.Character.Score.ToString();
                if (i > 0)
                    score = opponents[i - 1].Character.Score.ToString();
                else color = Color.Yellow;
                spriteBatch.DrawString(font, score, new Vector2(innerBounds.X + columnScoreX + textMargin, innerBounds.Y + (i * lineSpacing)), color);
            }
        }
        /// <summary>
        /// Draws the scores column, which shows all deaths per player.
        /// </summary>
        /// <param name="spriteBatch"></param>
        private void DrawDeathsColumn(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(backgroundTexture, new Rectangle(innerBounds.X + columnDeathsX, innerBounds.Y, 1, innerBounds.Height), lineColor * (1 - transparency));
            for (int i = 0; i <= opponents.Count; i++)
            {
                Color color = Color.White;
                string deaths = Player.Instance.Character.Deaths.ToString();
                if (i > 0)
                    deaths = opponents[i - 1].Character.Deaths.ToString();
                else color = Color.Yellow;
                spriteBatch.DrawString(font, deaths, new Vector2(innerBounds.X + columnDeathsX + textMargin, innerBounds.Y + (i * lineSpacing)), color);
            }
        }
        /// <summary>
        /// Draws the scores column, which shows all pings per player.
        /// </summary>
        /// <param name="spriteBatch"></param>
        private void DrawPingsColumn(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(backgroundTexture, new Rectangle(innerBounds.X + columnPingX, innerBounds.Y, 1, innerBounds.Height), lineColor * (1 - transparency));
            for (int i = 0; i <= opponents.Count; i++) //loop through opponents +1
            {
                Color color = Color.White;
                string ping = Player.Instance.Ping.ToString();
                if (i > 0)
                    ping = opponents[i - 1].Ping.ToString();
                else color = Color.Yellow;
                spriteBatch.DrawString(font, ping, new Vector2(innerBounds.X + columnPingX + textMargin, innerBounds.Y + (i * lineSpacing)), color);
            }
        }
    }
}
